﻿Imports WiremetModel.Entities.Tracking
Imports WiremetModel.Entities
Imports WiremetModel.Specification.GeneralSpecifications

Public Class frmKontrolaSzukaj2

    Private _unitOfWork As UnitOfWork
    Private _zleceniaTrackingDictionary As Dictionary(Of Integer, Zlecenie)

    Private Structure PozycjaZleceniaFilter        
        Public numerDrutu As Integer
        Public wymiar As String
    End Structure

    Private Structure ZlecenieFilter
        Public numerZlecenia As String
        Public klientId As Integer
        Public isDateFilterEnabled As Boolean
        Public dateStart As Date
        Public dateEnd As Date
        Public statusZleceniaId As Integer
        Public statusWysylkiId As Integer
    End Structure

    Private _initialRowCount As Integer = 10

    Public Sub New()

        InitializeComponent()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        SetInitialFilter()
        dgv_PozycjeZlecenia.RowCount = _initialRowCount

    End Sub

    Private Sub frmKontrolaSzukaj_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        _unitOfWork.Dispose()
    End Sub


    Private Sub RefreshViewData()

        Dim zleceniaTrackingRepository As New Repository(Of Zlecenie)(_unitOfWork)
        Dim klientRepository As New Repository(Of OEM.Klient)(_unitOfWork)
        Dim statusZleceniaRepository As New Repository(Of OEM.Status)(_unitOfWork)
        Dim statusWysylkiRepository As New Repository(Of OEM.StatusWysylki)(_unitOfWork)

        'Dim statusIdSpecification_1 As New StatusIdSpecification(Of PozycjaZlecenia)(1)
        'Dim statusIdSpecification_6 As New StatusIdSpecification(Of PozycjaZlecenia)(6)
        'Dim statusIdSpecification_7 As New StatusIdSpecification(Of PozycjaZlecenia)(7)

        '_pozycjeZlecenTrackingDictionary = pozycjeZleceniaTrackingRepository.GetAllMatching(statusIdSpecification_1.Negate()).ToDictionary(Function(x) x.Id, Function(x) x)
        '.Where(Function(x) x.Status.Id <> 1 AndAlso x.Status.Id <> 6 AndAlso x.Status.Id <> 7).
        _zleceniaTrackingDictionary = zleceniaTrackingRepository.GetAll().ToDictionary(Function(x) x.Id, Function(x) x)
        Dim klientList As IEnumerable(Of OEM.Klient) = klientRepository.GetAll().OrderBy(Function(x) x.NazwaSkrocona)
        Dim statusZleceniaList As IEnumerable(Of OEM.Status) = statusZleceniaRepository.GetAll().OrderBy(Function(x) x.Nazwa)
        Dim statusWysylkiList As IEnumerable(Of OEM.StatusWysylki) = statusWysylkiRepository.GetAll().OrderBy(Function(x) x.Nazwa)

        InitializeFilterComboBox(cmb_Klient, klientList.ToDictionary(Function(x) x.Id, Function(x) x.NazwaSkrocona))
        InitializeFilterComboBox(cmb_StatusZlecenia, statusZleceniaList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))
        InitializeFilterComboBox(cmb_StatusWysyłki, statusWysylkiList.ToDictionary(Function(x) x.Id, Function(x) x.Nazwa))

    End Sub

    Private Sub InitializeFilterComboBox(ByRef cmbFilter As ComboBox, ByVal data As Dictionary(Of Integer, String))

        cmbFilter.DataSource = New BindingSource(data, Nothing)
        cmbFilter.DisplayMember = "Value"
        cmbFilter.ValueMember = "Key"
        cmbFilter.AutoCompleteCustomSource.Clear()
        cmbFilter.AutoCompleteCustomSource.AddRange(data.Values.OrderBy(Function(x) x).ToArray())
        cmbFilter.SelectedIndex = -1

    End Sub

    Private Sub SetInitialFilter()
        cmb_StatusZlecenia.SelectedValue = 4
    End Sub

    Private Sub InsertInitialRows(ByVal zlecenieStack As Stack(Of Zlecenie))
        Dim zlecenieFilter As ZlecenieFilter = GetZlecenieFilter()
        Dim pozycjaZleceniaFilter As PozycjaZleceniaFilter = GetPozycjaZleceniaFilter()

        While dgv_PozycjeZlecenia.RowCount < _initialRowCount AndAlso zlecenieStack.Any()

            Dim zlecenie As Zlecenie = zlecenieStack.Pop()
            If IsZlecenieSatisfiedByFilter(zlecenie, zlecenieFilter) Then
                For Each pozycjaZlecenia As PozycjaZlecenia In zlecenie.PozycjeZlecenia.Values
                    If IsPozycjaZleceniaSatisfiedByFilter(pozycjaZlecenia, pozycjaZleceniaFilter) Then
                        Dim index As Integer = AddRowPozycjaZlecenia(zlecenie, pozycjaZlecenia)
                        ColorizeRow(pozycjaZlecenia, index)
                    End If
                Next
            End If
        End While
    End Sub

    Private Sub dgv_PozycjeZlecenia_CellValueNeeded(ByVal sender As Object, ByVal e As DataGridViewCellValueEventArgs) Handles dgv_PozycjeZlecenia.CellValueNeeded

        ' If this is the row for new records, no values are needed. 
        If e.RowIndex = dgv_PozycjeZlecenia.RowCount - 1 Then
            Return
        End If

        Dim zlecenieId As Integer = CInt(dgv_PozycjeZlecenia.Rows(e.RowIndex).Cells("ZlecenieId").Value)
        Dim pozycjaZleceniaId As Integer = CInt(dgv_PozycjeZlecenia.Rows(e.RowIndex).Cells("PozycjaZleceniaId").Value)

        Dim pozycjaZleceniaTmp As PozycjaZlecenia = _zleceniaTrackingDictionary(zlecenieId).PozycjeZlecenia(pozycjaZleceniaId)

        ' Set the cell value to paint using the Customer object retrieved. 
        Select Case dgv_PozycjeZlecenia.Columns(e.ColumnIndex).Name
            Case "colNumerZlecenia"
                e.Value = pozycjaZleceniaTmp.Zlecenie.Numer
            Case "colNazwaKlienta"
                e.Value = pozycjaZleceniaTmp.Zlecenie.Klient.NazwaSkrocona
            Case "colDataRealizacji"
                e.Value = pozycjaZleceniaTmp.Zlecenie.Termin
            Case "colGatunek"
                e.Value = pozycjaZleceniaTmp.Gatunek.NazwaAng
            Case "colWymiar"
                e.Value = pozycjaZleceniaTmp.Wymiar
            Case "colIlosc"
                e.Value = pozycjaZleceniaTmp.Ilosc
            Case "StatusZlecenia"
                e.Value = pozycjaZleceniaTmp.Zlecenie.Status.Nazwa
            Case "StatusWysylki"
                e.Value = pozycjaZleceniaTmp.Zlecenie.ZlecenieOEM.StatusWysylki.Nazwa
        End Select

    End Sub




    Private Function AddRowPozycjaZlecenia(ByVal zlecenie As Zlecenie, ByVal pozycjaZlecenia As PozycjaZlecenia) As Integer
        Return dgv_PozycjeZlecenia.Rows.Add(
                pozycjaZlecenia.Id,
                zlecenie.Numer,
                zlecenie.Klient.NazwaSkrocona,
                zlecenie.Termin.ToShortDateString(),
                pozycjaZlecenia.Gatunek.NazwaAng,
                pozycjaZlecenia.Wymiar,
                pozycjaZlecenia.Ilosc,
                zlecenie.Status.Nazwa,
                zlecenie.ZlecenieOEM.StatusWysylki.Nazwa)
    End Function

    Private Sub ColorizeRow(ByVal pozycjaZlecenia As PozycjaZlecenia, ByVal index As Integer)
        If pozycjaZlecenia.Schematy.Values.SelectMany(Function(x) x.PozycjeSchematu.Values).SelectMany(Function(x) x.Druty.Values).Any(Function(x) x.Opcja.Id = 4) Then
            dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Green400
        Else
            Select Case CType(pozycjaZlecenia.Zlecenie.Termin, Date).ToShortDateString
                Case CStr(Date.Today)
                    dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Yellow500
                Case CStr(DateSerial(Today.Year, Today.Month, Today.Day + 1))
                    dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Yellow500
                Case Is < CStr(DateSerial(Today.Year, Today.Month, Today.Day))
                    dgv_PozycjeZlecenia.Rows(index).DefaultCellStyle.BackColor = My.Settings.Red350
            End Select
        End If
    End Sub


#Region "Filter"

    Private Function GetZlecenieFilter() As ZlecenieFilter

        Return New ZlecenieFilter With {
            .numerZlecenia = tb_NumerZlecenia.Text.Trim(),
            .klientId = CInt(cmb_Klient.SelectedValue),
            .isDateFilterEnabled = cb_DataRealizacji.Checked,
            .dateStart = dtp_DataRealizacjiOd.Value.Date,
            .dateEnd = dtp_DataRealizacjiDo.Value.Date,
            .statusZleceniaId = CInt(cmb_StatusZlecenia.SelectedValue),
            .statusWysylkiId = CInt(cmb_StatusWysyłki.SelectedValue)
        }
    End Function


    Private Function GetPozycjaZleceniaFilter() As PozycjaZleceniaFilter
        Dim numerDrutu As Integer = 0
        Integer.TryParse(tb_NumerDrutu.Text.Trim(), numerDrutu)

        Return New PozycjaZleceniaFilter With {
            .wymiar = tb_FiltrWymiar.Text.Trim(),
            .numerDrutu = numerDrutu
        }
    End Function


    Private Function IsZlecenieSatisfiedByFilter(ByVal zlecenie As Zlecenie, ByVal filter As ZlecenieFilter) As Boolean

        Return zlecenie.Numer.StartsWith(filter.numerZlecenia, StringComparison.CurrentCultureIgnoreCase) AndAlso
               (filter.klientId = 0 OrElse zlecenie.Klient.Id = filter.klientId) AndAlso
               (Not filter.isDateFilterEnabled OrElse (zlecenie.Termin >= filter.dateStart AndAlso zlecenie.Termin <= filter.dateEnd)) AndAlso
               (filter.statusZleceniaId = 0 OrElse zlecenie.Status.Id = filter.statusZleceniaId) AndAlso
               (filter.statusWysylkiId = 0 OrElse zlecenie.ZlecenieOEM.StatusWysylki.Id = filter.statusWysylkiId)
    End Function

    Private Function IsPozycjaZleceniaSatisfiedByFilter(ByVal pozycjaZlecenia As PozycjaZlecenia, ByVal filter As PozycjaZleceniaFilter) As Boolean

        Return (filter.numerDrutu = 0 OrElse pozycjaZlecenia.Schematy.Values.SelectMany(Function(x) x.PozycjeSchematu.Values).SelectMany(Function(x) x.Druty.Values).Any(Function(x) x.Id = filter.numerDrutu AndAlso x.Opcja.Id = 4)) AndAlso
               (filter.wymiar = String.Empty OrElse pozycjaZlecenia.Wymiar.StartsWith(filter.wymiar, StringComparison.CurrentCultureIgnoreCase))

    End Function


    Private Sub RunFilter()

        ComboBoxCleanupWhenNoValueSelected(cmb_Klient)
        ComboBoxCleanupWhenNoValueSelected(cmb_StatusZlecenia)
        ComboBoxCleanupWhenNoValueSelected(cmb_StatusWysyłki)

    End Sub


    Private Sub ComboBoxCleanupWhenNoValueSelected(ByRef comboBox As ComboBox)
        If comboBox.SelectedValue Is Nothing Then
            comboBox.ResetText()
        End If
    End Sub


    Private Sub ClearFilter()

        tb_NumerZlecenia.Text = String.Empty
        cmb_Klient.ResetText()
        cmb_Klient.SelectedIndex = -1
        dtp_DataRealizacjiOd.Value = Now.Date
        dtp_DataRealizacjiDo.Value = Now.Date
        cb_DataRealizacji.Checked = False
        cmb_StatusZlecenia.ResetText()
        cmb_StatusZlecenia.SelectedIndex = -1
        tb_FiltrWymiar.Text = String.Empty
        tb_NumerDrutu.Text = String.Empty

    End Sub
#End Region




    Private Sub dgv_PozycjeZlecenia_CellMouseDoubleClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgv_PozycjeZlecenia.CellMouseDoubleClick

        Try
            If dgv_PozycjeZlecenia.SelectedRows.Count = 0 Then
                Throw New Exception("Wybierz zlecenie.")
            End If

            Dim biuroCredentials As OEM.Uprawienie = User.Role.GetValueOrDefault("biuro")

            If Not biuroCredentials.WyznModyfikacji AndAlso Not biuroCredentials.WyznOdczytu Then
                Throw New Exception("Nie masz wystarczających uprawnień.")
            End If

            Dim pozycjaZleceniaId As Integer = CInt(dgv_PozycjeZlecenia.SelectedRows(0).Cells("PozycjaZleceniaId").Value)
            Me.Cursor = Cursors.WaitCursor

            Dim repoPozycjaZlecenia As New Repository(Of PozycjaZlecenia)(_unitOfWork)
            Dim pozycjaZleceniaSpec As New IdSpecification(Of PozycjaZlecenia)(pozycjaZleceniaId)

            Dim kontrolaForm As New frmKontrola(repoPozycjaZlecenia.GetEntityMatching(pozycjaZleceniaSpec))
            kontrolaForm.MdiParent = MdiParent
            kontrolaForm.Show()

        Catch ex As Exception
            MessageBox.Show(ex.Message, "WIREMET", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        Finally
            Me.Cursor = Cursors.Default
        End Try

    End Sub


    Private Sub dtpDataRealizacji_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dtp_DataRealizacjiDo.ValueChanged, dtp_DataRealizacjiOd.ValueChanged
        cb_DataRealizacji.Checked = True
    End Sub

    Private Sub btn_RunFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_RunFilter.Click
        RunFilter()
    End Sub

    Private Sub btn_Refresh_Click(sender As System.Object, e As System.EventArgs) Handles btn_Refresh.Click
        _unitOfWork.Dispose()
        _unitOfWork = New UnitOfWork()
        RefreshViewData()
        ClearFilter()
        SetInitialFilter()
        RunFilter()
    End Sub

    Private Sub btn_ClearFilter_Click(sender As System.Object, e As System.EventArgs) Handles btn_ClearFilter.Click
        ClearFilter()
        RunFilter()
    End Sub

    Private Sub filterInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tb_NumerZlecenia.KeyDown, cmb_Klient.KeyDown, tb_NumerDrutu.KeyDown, tb_FiltrWymiar.KeyDown, cmb_StatusZlecenia.KeyDown, cmb_StatusWysyłki.KeyDown
        If e.KeyCode = Keys.Enter Then
            RunFilter()
        End If
    End Sub

End Class